New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MoveIt! tf2 migration #830
Conversation
|
Just work with it locally until ros/geometry2#292 is merged upstream.
We will not merge this request earlier anyway...
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huge PR!!
tf::pointEigenToMsg(contact.pos, msg.position); | ||
tf::vectorEigenToMsg(contact.normal, msg.normal); | ||
msg.position = tf2::toMsg(contact.pos); | ||
// FIXME: there really should be a conversion for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// TODO(IanTheEngineer)
@@ -275,8 +275,12 @@ void robot_trajectory::RobotTrajectory::getRobotTrajectoryMsg(moveit_msgs::Robot | |||
trajectory.multi_dof_joint_trajectory.points[i].transforms.resize(mdof.size()); | |||
for (std::size_t j = 0; j < mdof.size(); ++j) | |||
{ | |||
tf::transformEigenToMsg(waypoints_[i]->getJointTransform(mdof[j]), | |||
trajectory.multi_dof_joint_trajectory.points[i].transforms[j]); | |||
// FIXME: there should be a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
@@ -69,8 +67,6 @@ class CHOMPPlanningContext : public planning_interface::PlanningContext | |||
private: | |||
CHOMPInterfacePtr chomp_interface_; | |||
moveit::core::RobotModelConstPtr robot_model_; | |||
|
|||
boost::shared_ptr<tf::TransformListener> tf_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lol...
context_->planning_scene_monitor_->getTFClient()->getLatestCommonTime(pose_msg.header.frame_id, target_frame, | ||
common_time, &error); | ||
int pf = context_->planning_scene_monitor_->getTFClient()->_lookupFrameNumber(pose_msg.header.frame_id); | ||
int cf = context_->planning_scene_monitor_->getTFClient()->_lookupFrameNumber(target_frame); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better var names
@@ -88,7 +90,9 @@ bool PointCloudOctomapUpdater::setParams(XmlRpc::XmlRpcValue& params) | |||
|
|||
bool PointCloudOctomapUpdater::initialize() | |||
{ | |||
tf_ = monitor_->getTFClient(); | |||
tf_buffer_.reset(new tf2_ros::Buffer()); | |||
// FIXME(imcmahon) should the TransformListener use the private_nh_, root_nh_ or create it's own NodeHandle? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
// FIXME!(imcmahon) this forces the Planning Scene Monitor to allocate a new tf2_ros::Buffer | ||
// and tf2_ros::TransformListener on each invocation. These instances are properly deleted on exit, | ||
// but it would be better to remove the null shared pointer once tf2_ros::Buffer is exposed from | ||
// RViz with something like context_->getFrameManager()->getTFClientPtr() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
Commit 2da2c8d depends on ros-visualization/rviz#1224, and resolves the two main issues when dealing with transforms from RViz: the crashes no longer manifest. |
move_group_.reset(new moveit::planning_interface::MoveGroupInterface( | ||
opt, std::shared_ptr<tf2_ros::Buffer>(), ros::WallDuration(30, 0))); | ||
opt, context_->getFrameManager()->getTFBufferPtr(), ros::WallDuration(30, 0))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This depends on ros-visualization/rviz#1224
33e4c48
to
1ea1e00
Compare
@IanTheEngineer let me know when you've pushed everything to geometry2 and I can get a new release out in melodic |
@tfoote all the changes that I need are now merged into geometry2, so I think you're good to go in releasing to Melodic. Thanks! |
423ee0c
to
3703897
Compare
@davetcoleman and @v4hn I think this PR should build cleanly now that the dependencies have been merged into Melodic. However, the pull request builder is using Kinetic. How do I update the builder to use the right distro? |
For now I think we'll need to go without the pull request builder, I have not had time to set this up yet. Can you remove this from the first description if its ready?
You have an unfinished TODO in the first description:
These are ready? |
I can rebase this down now, but I typically do this right before a merge, after the reviews are made and feedback is incorporated. Keeping them separate helps in viewing the history of the PR, but I admit 40 commits is an unwieldy number.
Yep. All of the code is ready. I'll update the checkbox accordingly. |
Please wait with squashing. I'm currently reviewing... |
@rhaschke gotcha. I'll hold off on the squash until I have sufficient reviews. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally I approve these changes. @IanTheEngineer, thanks a lot for this great work! Some minor remarks inline.
@tfoote This PR uses the methods _addTransformsChangedListener
and _getLatestCommonTime
of tf2::BufferCore
, which are declared "not to be used anymore". What are the recommended alternatives?
try | ||
{ | ||
tf_->transformPose(frame_id_, input_pose, out_pose); | ||
// TODO: check logic here - which global collision body's transform should be used? | ||
input_transform.setData(robot_state->getAttachedBody(contextIt->second->frame_id_)->getGlobalCollisionBodyTransforms()[0]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not keep the previous code here?
input_transform.setData(robot_state->getLinkState(contextIt->second->frame_id_)->getGlobalCollisionBodyTransform());
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, transfom_provider
is never actually compiled, and if it were to be compiled, it would introduce a circular dependency between moveit_ros_perception
and moveit_ros_planning
, due to its use of planning_scene_monitor
.
Additionally, it turns out the functiongetGlobalCollisionBodyTransform
doesn't exist anywhere in the codebase. In order to make sure all of my other updates to this file were correct (tf2 message & type conversions, etc), I forced the compile of this file, which fails on this line. I put a band-aid on it to allow compiling, but it's likely not correct. I'm not sure what the proper procedure should be with this dead code.
if (!s.tf_) | ||
s.tf_.reset(new tf::TransformListener()); | ||
return s.tf_; | ||
if (!s.tf_buffer_ || !s.tf_listener_) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't it suffice to check for listener? Both, buffer and listener, are always created together?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is correct, both the buffer and the listener should be created together, and therefore just checking the for the listener should suffice. I structured this as such out of an abundance of caution in case the buffer is somehow deleted: the SharedStorage
is a struct
, making tf_buffer_
a public
method. However, you are right that this logic can be simplified.
return s.tf_; | ||
if (!s.tf_buffer_ || !s.tf_listener_) | ||
{ | ||
if(s.tf_listener_) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for this. Buffer is a shared_ptr
anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true, the buffer will continue to persist.
tf::matrixEigenToTF(current_state->getGlobalLinkTransform(lm).rotation(), ptf); | ||
tfScalar pitch, roll, yaw; | ||
ptf.getRPY(roll, pitch, yaw); | ||
geometry_msgs::TransformStamped tfs = tf2::eigenToTransform(current_state->getGlobalLinkTransform(lm)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
YPR can be directly computed from Eigen:
// yaw, pitch, roll corresponds to rotations about z, y, x axes, i.e. indeces 2, 1, 0 - in that order
Eigen::Map<Eigen::Vector3d>(&result[0]) = current_state->getGlobalLinkTransform(lm).rotation().eulerAngles(2, 1, 0)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well that's nifty. I'll update with your Eigen method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rhaschke wouldn't this line store the values in result
as [yaw, pitch, roll]
when result
is expecting [roll, pitch, yaw]
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Damn. Haven't seen that. Indeed, this would required to switch roll and yaw or to reverse()
the result of eulerAngles()
:
Eigen::Map<Eigen::Vector3d>(&result[0]) = current_state->getGlobalLinkTransform(lm).rotation().eulerAngles(2, 1, 0).reverse()
However, I'm completely fine, if you decide to keep your code for better readibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll use your updated Eigen method. I think a comment will suffice for readability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After fiddling with this for a bit, I think I will keep the original tf2
conversion code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reading this through it looks good. @rhaschke had a few suggestions that looked good too. I'm not likely to have a chance to run through again so +1
6864801
to
6de8b83
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@IanTheEngineer In view of the upcoming Melodic release, I'm fine to skip the replacement of deprecated methods _addTransformsChangedListener
and _getLatestCommonTime
for now ;-)
However, you should check for Travis' complaints.
@rhaschke I'm actually pretty close to fixing |
- All type conversions now depend on geometry2 ROS packages, rather than geometry (see ros/geometry2#292 and ros/geometry2#294 for details of the new conversions) - Removes all boost::shared_ptr<tf::TransformListener> from the API, and replaced them with std::shared_ptr<tf2_ros::Buffer>'s - Piped tf2_ros::Buffer's everywhere where tf::TransformListeners were used - Utilizes the new tf2 API in the tf::Transformer library to access the internal tf2::Buffer object used by RViz (see ros/geometry#163 for details of the new API) - Removes the prepending of forward slashes ('/') for Transforms frames as this is deprecated in tf2
6de8b83
to
c09d6bb
Compare
I squashed most of the history of this PR, but it's still not quite ready for merging. I still have to
As it would require fully grokking how |
881ee93
to
8c3f2d7
Compare
At this point, I think the only reason Travis is failing is that it's attempting to build with kinetic. |
@rhaschke thanks for the fix - seems I incorrectly melded that file. |
I'm currently looking into Travis / docker to fix our CI for melodic. |
const ros::WallDuration& wait_for_servers = ros::WallDuration()); | ||
MOVEIT_DEPRECATED MoveGroupInterface(const Options& opt, const boost::shared_ptr<tf::Transformer>& tf, | ||
MOVEIT_DEPRECATED MoveGroupInterface(const Options& opt, const std::shared_ptr<tf2_ros::Buffer>& tf_buffer, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it time to drop everything marked with MOVEIT_DEPRECATED
instead of migrating them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, we should have a check for deprecated stuff. But we should carefully check, when and why we deprecated. I would only remove stuff that was deprecated in Indigo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point of keeping them with the deprecated flag was that they remain unchanged. If we keep updating their signature, the original functions are gone regardless.
I think the two scallywags below should be removed instead of updating them even though they were not deprecated already in Indigo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no preference on updating or removing. However, for the purposes of preventing this PR from becoming too big and unwieldy, I tried to use a light touch in only updating what I absolutely had to update for tf2 to work.
I think another PR is in order for removing all MOVEIT_DEPRECATED
functions from the Lunar/Kinetic release for Melodic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... which I see you just recommended in #902 (comment). Appears we're on the same page @bmagyar :)
I approved that this compiles for Melodic and I'm going to squash-merge now. |
I'm fine with that, all of the changes are now in. Would you prefer that I squash everything manually in order to preserve the (hopefully informative) commit message? |
Nevermind! Looks like you handled it beautifully. Thanks @rhaschke! And thanks to everyone else for the reviews and feedback. It was a nice birthday present to have this merged today 🎂 😄 |
This will resolve #745 and complete a checkbox for Release to Melodic.
This is the migration from
tf
totf2
required forROS2
. It depends on ros/geometry2#292 for a handful of additional conversions. It breaks API compatibility, so it can only be merged into themelodic-devel
branch.This PR depends on the following upstream API changes for Melodic:
ros/geometry#163 (Exposing
tf2_ros::Buffer
object from TransformListener)ros/geometry2#292 (tf2 Type conversions)
ros/geometry2#294 (Additional tf2 Type conversions)
ros-visualization/rviz#1236 (Exposing tf2 without ROS deprecation warnings)
Highlights:
geometry2
ROS packages, rather thangeometry
boost::shared_ptr<tf::TransformListener>
from the API, and replaced them withstd::shared_ptr<tf2_ros::Buffer>
's. I figured boost was only kept to preserve API, but please correct me if that is a bad assumption.tf2_ros::Buffer
's everywhere wheretf::TransformListener
s were usedThings left TODO:
tf2_ros::Buffer
instance, as RViz APi only gives access to theboost::shared_ptr<tf::TransformListener>
instance:Migrating RViz DisplayContext to tf2 ros-visualization/rviz#1215
My solution was to just pass in a null
Buffer
to themove_group
when we would have used RViz'sTransformListener
. This almost seems to work, aside for the bug.Checklist
melodic-devel
only